package com.hw.backapi.context;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;

/**
 * alioss
 */
@Component
@Slf4j
public class AliOssContext {
    @Value("${oss.aliyun.endpoint}")
    private String endpoint;
    @Value("${oss.aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${oss.aliyun.accessKeySecret}")
    private String accessKeySecret;
    @Value("${oss.aliyun.bucketName}")
    private String ossBucketName;

    public String getOssBucketName(){
        return this.ossBucketName;
    }

    public OSS ossClient = null;

    public OSS getOssClient(){
        if (ossClient == null) {
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        }
        return ossClient;
    }

    /**
     * 上传文件到oss
     * @param file
     * @param sourceFile
     * @return
     */
    public String uploadOssFile(String file, InputStream sourceFile) {
        String descFile = file;
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(ossBucketName, descFile, sourceFile);
            String contentType = getContentType(file);
            if (contentType != null) {
                ObjectMetadata meta = new ObjectMetadata();
                meta.setContentType(contentType);
                putObjectRequest.setMetadata(meta);
            }
            PutObjectResult putObjectResult = getOssClient().putObject(putObjectRequest);
            // 设置URL过期时间为1小时。
//            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
//            String url = ossClient.generatePresignedUrl(ossBucketName, descFile, expiration).toString();
            log.info("文件上传OSS成功！");
        } catch (Exception e) {
//            e.printStackTrace();
            descFile = "";
            log.error("文件上传OSS错误。");
        }
        return descFile;
    }


    public String generateUrl(String descFile){
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
            return getOssClient().generatePresignedUrl(ossBucketName, descFile, expiration).toString();
    }

    public void listFile(){
        // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
        ObjectListing objectListing = getOssClient().listObjects(ossBucketName);
        // objectListing.getObjectSummaries获取所有文件的描述信息。
        for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
            System.out.println(" - " + objectSummary.getKey() + "  " +
                    "(size = " + objectSummary.getSize() + ")");
        }
    }

    public void downloadFile(String fileName , String outputFileName, HttpServletResponse  response){
        BufferedInputStream input = null;
        OutputStream outputStream = null;

        // 创建OSSClient实例。
        try {
            OSSObject ossObject = getOssClient().getObject(ossBucketName, fileName);
            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/x-msdownload");
            response.addHeader("Content-Disposition",
                    "attachment;filename=" + new String(outputFileName.getBytes("gb2312"), "ISO8859-1"));

            input = new BufferedInputStream(ossObject.getObjectContent());
            byte[] buffBytes = new byte[1024];
            outputStream = response.getOutputStream();
            int read = 0;
            while ((read = input.read(buffBytes)) != -1) {
                outputStream.write(buffBytes, 0, read);
            }
            outputStream.flush();
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            ossObject.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (input != null) {
                    input.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    @PreDestroy
    public void detory() {
        getOssClient().shutdown();
        System.out.println("detory");
    }

    /**
     * 返回文件的MIME类型
     *
     * @param FilenameExtension
     * @return String
     */
    private String getContentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp4")) {
            return "video/mp4";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp3")) {
            return "audio/mpeg";
        }
        return null;
    }
}
